﻿using ConfigInfoWebPlatform.API.BusinessCommon;
using ConfigInfoWebPlatform.API.DBCommon;
using ConfigInfoWebPlatform.API.ViewModel;
using ConfigInfoWebPlatform.Model;
using ConfigInfoWebPlatform.Nlog;
using FileSecretAssemblyStandard;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Scripting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ConfigInfoWebPlatform.API.Controllers
{
    /// <summary>
    /// 添加用户权限
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class UserAuthorityController : ControllerBase
    {
        readonly LogHelper _log;
        readonly string configRootPath;
        readonly InterfaceFileSecret FileSecret;
        /// <summary>
        /// 实例化构造函数
        /// </summary>
        public UserAuthorityController(LogHelper logHelper, IConfiguration configuration, InterfaceFileSecret fileSecret)
        {
            _log = logHelper;
            configRootPath = configuration["AppSetting:configPath"].ToString();
            FileSecret = fileSecret;
        }
        /// <summary>
        /// 用户登录验证
        /// </summary>
        /// <returns></returns>
        [HttpPost("loginverify")]
        public IActionResult LoginVerify() 
        {
            // 获取请求过来的json数据
            var sr = new StreamReader(Request.Body);
            var strcontent = sr.ReadToEnd();
            sr.Close();
           var userinfo= Newtonsoft.Json.JsonConvert.DeserializeObject<UserInfoViewModel>(strcontent);
            DAL_UserInfo userInfoDal = new DAL_UserInfo();
            var userres= userInfoDal.GetUser(userinfo);
            if (userres != null)
            {
                var result = new
                {
                    user = Base64Helper.EnCodeBase64(65001, Newtonsoft.Json.JsonConvert.SerializeObject(userres)),
                };
                return new JsonResult(result);
            }
            else 
            {
                return BadRequest();
            }
        }

        /// <summary>
        /// 用户列表
        /// </summary>
        [HttpGet("index")]
        public IActionResult Index(int page,int limit,string name)
        {
            //获取当前登录用户信息
            UserInfoModel identity = new UserInfoModel();
            var userJsonStr = Base64Helper.DeCodeBase64(65001, Request.Headers["user"]);
            identity = Newtonsoft.Json.JsonConvert.DeserializeObject<UserInfoModel>(userJsonStr);
            List<UserListModel> list = new List<UserListModel>();
            List<UserListModel> pageList = new List<UserListModel>();
            DAL_UserInfo userInfoDal = new DAL_UserInfo();
            //获取所有用户数据
            list = userInfoDal.GetUserList(name,identity.D_id,identity.Name=="admin"?true:false);
            int totalcount = 0;
            if (list.Any())
            {
                totalcount = list.Count;
                pageList = list.Skip((page - 1) * limit).Take(limit).ToList();
            }
            return new JsonResult(new { code = 0, msg = "success", count = totalcount, data = pageList });
        }

        /// <summary>
        /// 获取用户详情数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("detail")]
        public IActionResult Detail(string id)
        {
            UserInfoModel user = new UserInfoModel();
            DAL_UserInfo userInfoDal = new DAL_UserInfo();
            user = userInfoDal.GetUserDetail(id);
            return new JsonResult(new { code = 0, msg = "success", data = user });
        }

        /// <summary>
        /// 修改用户角色信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("saveuserrole")]
        public IActionResult SaveUserRoleInfo([FromBody] UserRoleSaveModel model)
        {
            DAL_UserInfo userInfoDal = new DAL_UserInfo();
            userInfoDal.EditUserRoleInfo(model.Id,model.Rid);
            return new JsonResult(new { code = 0, msg = "success"});
        }


        /// <summary>
        /// 通过登录名获取版本数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("getversionbyusername")]
        public IActionResult GetVersionByUserName(string userName)
        {
            List<VersionModel> list = new List<VersionModel>();
            //获取用户部门Id
            DAL_UserInfo userInfoDal = new DAL_UserInfo();
            string did = userInfoDal.GetUserDidByUserName(userName);
            //获取所有版本数据
            DAL_Version versionDal = new DAL_Version();
            list = versionDal.GetVersionList(did?.Replace("-",""), userName == "admin" ? true : false);
            return new JsonResult(new { code = 0, msg = "success", data = list });
        }

        /// <summary>
        /// 获取版本信息
        /// </summary>
        [HttpGet("getversionInfo")]
        public IActionResult GetVersionInfo(string id)
        {
            DAL_Version versionDal = new DAL_Version();
            var version = versionDal.GetVersionDetail(id);
            var versionPath = version?.Catalogue == "dev"
                                ? ""
                                : version?.Catalogue;
            var rootPath = Path.Combine(configRootPath, versionPath);
            var result = Base64Helper.EnCodeBase64(65001, Newtonsoft.Json.JsonConvert.SerializeObject(version));
            Task.Run(() => { CreateWholeProcess(rootPath); });
            return new JsonResult(result);
        }

        private void CreateWholeProcess(string rootPath)
        {
            var fileName = $"{rootPath}/config/wholeprocess.xml";
            if (!System.IO.File.Exists(fileName))
            {
                System.IO.File.Create(fileName).Close();
                XDocument xdocument = new XDocument();
                XDeclaration xdec = new XDeclaration("1.0", "utf-8", "yes");
                xdocument.Declaration = xdec;
                XElement root =new XElement("root");
                xdocument.Add(root);
                DAL_ProgramNavicat dal_programNavicat = new DAL_ProgramNavicat();
                var caseNavs = dal_programNavicat.GetCaseTypeNavicats();
                if (caseNavs != null && caseNavs.Any())
                {
                    foreach (var nav in caseNavs)
                    {
                        string caseName = nav.Name.Replace("流程", "");
                        string caseDir = nav.Directory;
                        string caseCode = Path.GetFileName(caseDir);
                        XElement caseTypeNode = new XElement("casetype");
                        caseTypeNode.SetAttributeValue("name", caseName);
                        caseTypeNode.SetAttributeValue("code", caseCode);
                        //添加卷宗节点
                        try
                        {
                            CreateDocNode(caseTypeNode, caseDir, rootPath);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        
                        root.Add(caseTypeNode);
                    }
                }
                //FileSecret.DecryptFileToContent(fileName);
                xdocument.Save(fileName);
            }
        }

        /// <summary>
        /// 生成卷宗节点数据
        /// </summary>
        private void CreateDocNode(XElement caseType, string dir,string rootPath)
        {
            DAL_DataSource sourceDal = new DAL_DataSource();
            var filePath = Path.Combine(rootPath, dir);
            if(Directory.Exists(filePath))
            {
                DirectoryInfo directory = new DirectoryInfo(filePath);
                DirectoryInfo[] childDir = directory.GetDirectories();
                string caseTypeCode = Path.GetFileNameWithoutExtension(dir);
                if (childDir != null && childDir.Any())
                {
                    foreach (DirectoryInfo docInfo in childDir)
                    {
                        var oldName = docInfo.FullName;
                        var lowerName = docInfo.Name.ToLower();
                        if (Regex.IsMatch(docInfo.Name, "[A-Z]"))
                        {
                            FileSystemObject fso = new FileSystemObjectClass();
                            try
                            {
                                var nameTemp = $"{docInfo.Name.ToLower()}1";
                                var allNameTemp = $"{docInfo.Parent.FullName}\\{nameTemp}";
                                fso.GetFolder(oldName).Name = nameTemp;
                                fso.GetFolder(allNameTemp).Name = lowerName;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }

                        }
                        //卷宗编号
                        var docCode = docInfo.Name.ToLower();
                        //卷宗名称
                        var docName = string.Empty;
                        var sourceInfo = sourceDal.GetDataSourceByCode(docCode, caseTypeCode);
                        if (sourceInfo != null)
                            docName = sourceInfo.Name;
                        XElement docTypeNode = new XElement("doctype");
                        docTypeNode.SetAttributeValue("name", docName);
                        docTypeNode.SetAttributeValue("code", docCode);
                        docTypeNode.SetAttributeValue("parentcode", caseTypeCode);
                        //添加流程节点
                        var currentCode = $"{caseTypeCode}_{docCode}";
                        CreateProcessNode(docTypeNode, docInfo.FullName, currentCode, rootPath);
                        caseType.Add(docTypeNode);
                    }
                }
            }
        }

        /// <summary>
        /// 生成流程节点数据
        /// </summary>
        private void CreateProcessNode(XElement docType, string docTypePath, string parentCode,string rootPath)
        {
            if(Directory.Exists(docTypePath))
            {
                DirectoryInfo directory = new DirectoryInfo(docTypePath);
                FileInfo[] fileInfos = directory.GetFiles().Where(x => !x.Extension.Contains("back")).ToArray();
                if (fileInfos != null && fileInfos.Any())
                {
                    foreach (FileInfo item in fileInfos)
                    {
                        var processName = item.Name;
                        var replacePath = rootPath.Replace("/", @"\");
                        var processPath = item.FullName.Replace($"{replacePath}\\", "");
                        XElement processNode = new XElement("process");
                        processNode.SetAttributeValue("name", processName);
                        processNode.SetAttributeValue("path", processPath.Replace("\\","/"));
                        processNode.SetAttributeValue("parentcode", parentCode);
                        var currentCode = $"{parentCode}_{processName}";
                        try
                        {
                            CreateModuleNode(processNode, item.FullName, currentCode);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        
                        docType.Add(processNode);
                    }
                }
            }
            
        }

        /// <summary>
        /// 生成模块节点数据
        /// </summary>
        /// <param name="process"></param>
        /// <param name="processPath"></param>
        /// <param name="parentCode"></param>
        private void CreateModuleNode(XElement process, string processPath, string parentCode)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(processPath))
                {
                    XElement processRoot = null;
                    string processContent = FileSecret.DecryptFileToContent(processPath);
                    if(!string.IsNullOrWhiteSpace(processContent))
                    {
                        XDocument processDoc = XDocument.Parse(processContent);
                        processRoot = processDoc.Element("root");
                        if(processRoot!=null)
                        {
                            List<XElement> processSteps = processRoot.Descendants()
                                                                 .Where(x => x.Name.LocalName == "step")
                                                                 .ToList();
                            if (processSteps != null && processSteps.Any())
                            {
                                foreach (XElement item in processSteps)
                                {
                                    var moduleName = item.Attribute("executecode").Value;
                                    var moduleCode = item.Attribute("code").Value;
                                    var modulePath = item.Attribute("executefile").Value;
                                    var moduleRemark = item.Attribute("zh_cn").Value;
                                    XElement moduleNode = new XElement("module");
                                    moduleNode.SetAttributeValue("name", moduleName);
                                    moduleNode.SetAttributeValue("code", moduleCode);
                                    moduleNode.SetAttributeValue("path", modulePath.Replace("\\","/"));
                                    moduleNode.SetAttributeValue("remark", moduleRemark);
                                    moduleNode.SetAttributeValue("parentcode", parentCode);
                                    process.Add(moduleNode);
                                }
                            }
                        }
                        
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            
        }

    }
}
